#ifndef _WX_HELPDATA_H_
#define _WX_HELPDATA_H_

#include "wx/defs.h"
#include "wx/object.h"
#include "wx/string.h"
#include "wx/filesys.h"
#include "wx/dynarray.h"
#include "wx/font.h"

class wxHtmlHelpData;

class wxHtmlBookRecord {
  public:
    wxHtmlBookRecord( const wxString& bookfile, const wxString& basepath,const wxString& title, const wxString& start ) {
      m_BookFile = bookfile;
      m_BasePath = basepath;
      m_Title = title;
      m_Start = start;
      // for debugging, give the contents index obvious default values
      m_ContentsStart = m_ContentsEnd = -1;
    }
    wxString GetBookFile() const { return m_BookFile; }
    wxString GetTitle() const { return m_Title; }
    wxString GetStart() const { return m_Start; }
    wxString GetBasePath() const { return m_BasePath; }
    void SetContentsRange( int start, int end ) { m_ContentsStart = start; m_ContentsEnd = end; }
    int GetContentsStart() const { return m_ContentsStart; }
    int GetContentsEnd() const { return m_ContentsEnd; }
    void SetTitle( const wxString& title ) { m_Title = title; }
    void SetBasePath( const wxString& path ) { m_BasePath = path; }
    void SetStart( const wxString& start ) { m_Start = start; }
    wxString GetFullPath( const wxString &page ) const;
  protected:
    wxString m_BookFile;
    wxString m_BasePath;
    wxString m_Title;
    wxString m_Start;
    int m_ContentsStart;
    int m_ContentsEnd;
};


WX_DECLARE_USER_EXPORTED_OBJARRAY( wxHtmlBookRecord, wxHtmlBookRecArray);

struct wxHtmlHelpDataItem {
  wxHtmlHelpDataItem() : level( 0 ), parent( NULL ), id( wxID_ANY ), book( NULL ) {}

  int level;
  wxHtmlHelpDataItem *parent;
  int id;
  wxString name;
  wxString page;
  wxHtmlBookRecord *book;
  wxString GetFullPath() const { return book->GetFullPath( page ); }
  wxString GetIndentedName() const;
};

WX_DECLARE_USER_EXPORTED_OBJARRAY( wxHtmlHelpDataItem, wxHtmlHelpDataItems);

class wxHtmlSearchEngine : public wxObject {
  public:
    wxHtmlSearchEngine() : wxObject() {}
    virtual ~wxHtmlSearchEngine() {}
    virtual void LookFor( const wxString& keyword, bool case_sensitive, bool whole_words_only );
    virtual bool Scan( const wxFSFile& file );

  private:
    wxString m_Keyword;
    bool m_CaseSensitive;
    bool m_WholeWords;

    DECLARE_NO_COPY_CLASS( wxHtmlSearchEngine )
};

class wxHtmlSearchStatus {
  public:
    wxHtmlSearchStatus( wxHtmlHelpData* base, const wxString& keyword,
                        bool case_sensitive, bool whole_words_only,
                        const wxString& book = wxEmptyString );
    bool Search();  // do the next iteration
    bool IsActive() { return m_Active; }
    int GetCurIndex() { return m_CurIndex; }
    int GetMaxIndex() { return m_MaxIndex; }
    const wxString& GetName() { return m_Name; }

    const wxHtmlHelpDataItem *GetCurItem() const { return m_CurItem; }

  private:
    wxHtmlHelpData* m_Data;
    wxHtmlSearchEngine m_Engine;
    wxString m_Keyword, m_Name;
    wxString m_LastPage;
    wxHtmlHelpDataItem* m_CurItem;
    bool m_Active;   // search is not finished
    int m_CurIndex;  // where we are now
    int m_MaxIndex;  // number of files we search
    DECLARE_NO_COPY_CLASS( wxHtmlSearchStatus )
};

class wxHtmlHelpData : public wxObject {
    DECLARE_DYNAMIC_CLASS( wxHtmlHelpData )
    friend class wxHtmlSearchStatus;

  public:
    wxHtmlHelpData();
    virtual ~wxHtmlHelpData();
    void SetTempDir( const wxString& path );
    bool AddBook( const wxString& book );
    bool AddBookParam( const wxFSFile& bookfile,
                       wxFontEncoding encoding,
                       const wxString& title, const wxString& contfile,
                       const wxString& indexfile = wxEmptyString,
                       const wxString& deftopic = wxEmptyString,
                       const wxString& path = wxEmptyString );
    wxString FindPageByName( const wxString& page );
    // returns URL of page on basis of MS id
    wxString FindPageById( int id );
    const wxHtmlBookRecArray& GetBookRecArray() const { return m_bookRecords; }
    const wxHtmlHelpDataItems& GetContentsArray() const { return m_contents; }
    const wxHtmlHelpDataItems& GetIndexArray() const { return m_index; }
  protected:
    wxString m_tempPath;

    // each book has one record in this array:
    wxHtmlBookRecArray m_bookRecords;

    wxHtmlHelpDataItems m_contents; // list of all available books and pages
    wxHtmlHelpDataItems m_index; // list of index itesm
  protected:
    // Imports .hhp files (MS HTML Help Workshop)
    bool LoadMSProject( wxHtmlBookRecord *book, wxFileSystem& fsys,
                        const wxString& indexfile, const wxString& contentsfile );
    // Reads binary book
    bool LoadCachedBook( wxHtmlBookRecord *book, wxInputStream *f );
    // Writes binary book
    bool SaveCachedBook( wxHtmlBookRecord *book, wxOutputStream *f );

    DECLARE_NO_COPY_CLASS( wxHtmlHelpData )
};

#endif
